/* Copyright 2009
 *
 * This program and the accompanying materials
 * are made available under the terms of the
 * Eclipse Public License v1.0 which accompanies
 * this distribution, and is available at
 *
 * 		http://www.eclipse.org/legal/epl-v10.html
 *
 * Unless required by applicable law or agreed to in
 * writing, software distributed under the License is
 * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
 * OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing
 * permissions and limitations under the License.
 *
 * Contributors:
 * 	   IBM Corporation - initial API and implementation for JDT/DLTK
 *     Sean W. Quinn - initial adoption for use with PHP from various sources.
 */
package org.eclipse.php.internal.core;

import java.util.ArrayList;
import java.util.Map;

import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.dltk.core.ModelException;
import org.eclipse.dltk.internal.core.ModelElementInfo;
import org.eclipse.dltk.internal.core.OpenableElementInfo;
import org.eclipse.php.core.IPHPElement;
import org.eclipse.php.core.IPHPModelStatusConstants;
import org.eclipse.php.core.IProgramUnit;
import org.eclipse.php.core.IScriptFile;

/**
 * A package fragment that represents a package fragment found in a JAR.
 *
 * @see org.eclipse.jdt.core.INamespaceFragment
 */
@SuppressWarnings("restriction")
class PharNamespaceFragment extends NamespaceFragment {
	/**
	 * Constructs a package fragment that is contained within a jar or a zip.
	 */
	protected PharNamespaceFragment(NamespaceFragmentRoot root, String[] names) {
		super(root, names);
	}

	/**
	 * @see Openable
	 */
	@Override
	protected boolean buildStructure(OpenableElementInfo info, IProgressMonitor pm, Map newElements,
			IResource underlyingResource) throws ModelException {
		PharNamespaceFragmentRoot root = (PharNamespaceFragmentRoot) getParent();
		PharNamespaceFragmentRootInfo parentInfo = (PharNamespaceFragmentRootInfo) root.getElementInfo();
		ArrayList[] entries = (ArrayList[]) parentInfo.rawPackageInfo.get(this.names);
		if (entries == null)
			throw newNotPresentException();
		PharNamespaceFragmentInfo fragInfo = (PharNamespaceFragmentInfo) info;

		// compute children
		fragInfo.setChildren(computeChildren(entries[0/* class files */]));

		// compute non-Java resources
		fragInfo.setNonPHPResources(computeNonPHPResources(entries[1]));

		newElements.put(this, fragInfo);
		return true;
	}

	/**
	 * Compute the children of this package fragment. Children of jar package
	 * fragments can only be IScriptFile (representing .class files).
	 */
	private IPHPElement[] computeChildren(ArrayList namesWithoutExtension) {
		// FIXME: Implement me!
		throw new RuntimeException(getClass().getName() + "#computeChildren() not yet implemented!");
	}

	/**
	 * Compute all the non-java resources according to the given entry names.
	 */
	private Object[] computeNonPHPResources(ArrayList entryNames) {
		// FIXME: Implement me!
		throw new RuntimeException(getClass().getName() + "#computeNonPHPResources() not yet implemented!");
	}

	/**
	 * Returns true if this fragment contains at least one java resource.
	 * Returns false otherwise.
	 */
	@Override
	public boolean containsPHPResources() throws ModelException {
		return ((PharNamespaceFragmentInfo) getElementInfo()).containsPHPResources();
	}

	/**
	 * @see org.eclipse.jdt.core.INamespaceFragment
	 */
	public IProgramUnit createCompilationUnit(String cuName, String contents, boolean force, IProgressMonitor monitor)
			throws ModelException {
		throw new ModelException(new PHPModelStatus(IPHPModelStatusConstants.READ_ONLY, this));
	}

	/**
	 * @see PHPElement
	 */
	@Override
	protected Object createElementInfo() {
		return new PharNamespaceFragmentInfo();
	}

	/**
	 * @see org.eclipse.jdt.core.INamespaceFragment
	 */
	public IScriptFile[] getClassFiles() throws ModelException {
		ArrayList list = getChildrenOfType(SCRIPT_FILE);
		IScriptFile[] array = new IScriptFile[list.size()];
		list.toArray(array);
		return array;
	}

	/**
	 * A jar package fragment never contains compilation units.
	 *
	 * @see org.eclipse.jdt.core.INamespaceFragment
	 */
	public IProgramUnit[] getCompilationUnits() {
		return NO_PROGRAM_UNITS;
	}

	/**
	 * A package fragment in a jar has no corresponding resource.
	 *
	 * @see IPHPElement
	 */
	@Override
	public IResource getCorrespondingResource() {
		return null;
	}

	/**
	 * Returns an array of non-java resources contained in the receiver.
	 */
	@Override
	public Object[] getNonPHPResources() throws ModelException {
		if (isDefaultNamespace()) {
			// We don't want to show non java resources of the default package (see PR #1G58NB8)
			return ModelElementInfo.NO_NON_SCRIPT_RESOURCES;
		}
		else {
			return storedNonPHPResources();
		}
	}

	/**
	 * Phars and jar entries are all read only
	 */
	@Override
	public boolean isReadOnly() {
		return true;
	}

	protected Object[] storedNonPHPResources() throws ModelException {
		//return ((PharNamespaceFragmentInfo) getElementInfo()).getNonPHPResources();
		// FIXME: Implement me!
		throw new RuntimeException(getClass().getName() + "#storedNonPHPResources() not yet implemented!");
	}
}
